package cn.iocoder.yudao.module.erp.service.gi;

import cn.iocoder.yudao.module.erp.controller.admin.dp.dpdx.vo.DpDxSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.gi.gidx.vo.GiDxPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.gi.gidx.vo.GiDxSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemDxDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.giitem.GiItemDxDO;
import cn.iocoder.yudao.module.erp.dal.mysql.gi.GiDxMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.giitem.GiItemDxMapper;
import cn.iocoder.yudao.module.erp.service.dp.DpDxServiceImpl;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import cn.iocoder.yudao.module.erp.dal.dataobject.gi.GiDxDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.GI_GZ_NOT_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.GI_INCOUNT_NOT_ZERO;

/**
 * ERP物流东线仓库 Service 实现类
 * @author 天使管理员
 */
@Service
@Validated
public class GiDxServiceImpl implements GiDxService {

    @Resource
    private GiDxMapper giDxMapper;
    @Resource
    private GiItemDxMapper giItemDxMapper;
    @Resource
    private AdminUserService userService;
    @Autowired
    private DpDxServiceImpl dpDxServiceImpl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createGiDx(GiDxSaveReqVO createReqVO) {
        Integer inCount = createReqVO.getInCount();
        if (inCount == null || inCount == 0) {
            throw exception(GI_INCOUNT_NOT_ZERO);
        }
        String maxId = generateOrderNumber();
        createReqVO.setId(maxId);
        // 插入
        GiDxDO giDx = BeanUtils.toBean(createReqVO, GiDxDO.class);
        giDxMapper.insert(giDx);
        // 插入子表
        createGiItemDxList(maxId, createReqVO.getGiItemDxs());
        // 返回
        return maxId;
    }

    public String generateOrderNumber() {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 格式化为 yyyyMMdd
        String dateStr = currentDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        // 获取当前最大单号的前8位和最后四位
        String currentMaxOrderStr = getCurrentMaxOrderNumber();
        if ("0001".equals(currentMaxOrderStr)){
            return "DX" + dateStr + currentMaxOrderStr;
        }
        // 获取当前最大单号的日期部分
        String currentMaxDateStr = currentMaxOrderStr.substring(2, 10);
        // 如果日期不一致，重置序列为0001
        int sequence;
        if (currentMaxDateStr.equals(dateStr)) {
            // 日期一致，则增加序列
            sequence = Integer.parseInt(currentMaxOrderStr.substring(10)) + 1;
        } else {
            // 日期不一致，则重置序列为 0001
            sequence = 1;
        }
        // 生成新的单号
        return "DX" + dateStr + String.format("%04d", sequence);
    }

    // 从数据库中获取当前最大单号
    private String getCurrentMaxOrderNumber() {
        // 此处应从数据库查询获取当前最大单号
        return giDxMapper.getCurrentMaxOrderNumber();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGiDx(GiDxSaveReqVO updateReqVO) {
        // 更新
        GiDxDO updateObj = BeanUtils.toBean(updateReqVO, GiDxDO.class);
        // 获得用户信息
        AdminUserDO user = userService.getUser(getLoginUserId());
        updateObj.setUpdater(user.getUsername());
        giDxMapper.updateById(updateObj);
        // 更新子表
        updateGiItemDxList(updateReqVO.getId(), updateReqVO.getGiItemDxs());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteGiDx(String id) {
        // 删除子表
        deleteGiItemDxByNo(id);
        // 删除
        giDxMapper.deleteById(id);
    }


    @Override
    public GiDxDO getGiDx(String id) {
        return giDxMapper.selectById(id);
    }

    @Override
    public PageResult<GiDxDO> getGiDxPage(GiDxPageReqVO pageReqVO) {
        return giDxMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（ERP物流东线仓库货号详情） ====================

    @Override
    public List<GiItemDxDO> getGiItemDxListByNo(String no) {
        return giItemDxMapper.selectListByNo(no);
    }

    @Override
    public void examineGiDx(GiDxDO giDxDO) {
        // 将 GiDxSaveReqVO 转换为 DpDxSaveReqVO,处理并保存插入到 DpDxSaveReqVO 对应的表
        convertGiDxToDpDx(giDxDO);
        giDxMapper.updateById(giDxDO);
    }

    private void createGiItemDxList(String no, List<GiItemDxDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        giItemDxMapper.insertBatch(list);
    }

    private void updateGiItemDxList(String no, List<GiItemDxDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        deleteGiItemDxByNo(no);
        list.forEach(o -> o.setNo(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createGiItemDxList(no, list);
    }

    private void deleteGiItemDxByNo(String no) {
        giItemDxMapper.deleteByNo(no);
    }

    // 将 GiDxSaveReqVO 转换为 DpDxSaveReqVO
    public void  convertGiDxToDpDx(GiDxDO giDxDO) {

        GiDxDO giDx = giDxMapper.selectById(giDxDO.getId());
        List<GiItemDxDO> giItemDxDOList = giItemDxMapper.selectListByNo(giDxDO.getId());
        // 复制 GiDxSaveReqVO 中的属性到 DpDxSaveReqVO
        DpDxSaveReqVO createReqVO = BeanUtils.toBean(giDx, DpDxSaveReqVO.class);
        //设置剩余总件数
        createReqVO.setRemCount(giDx.getInCount());
        //设置剩余总体积
        createReqVO.setRemVolume(giDx.getInVolume());
        //设置剩余总重量
        createReqVO.setRemWeight(giDx.getWeight());
        List<DpItemDxDO> dpItemDxs = BeanUtils.toBean(giItemDxDOList, DpItemDxDO.class);
        // 设置转换后的列表到 DpDxSaveReqVO
        createReqVO.setDpItemDxs(dpItemDxs);
        dpDxServiceImpl.createDpDx(createReqVO);
    }

}